package com.wei.czz.framework.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wei.czz.common.dto.common.GroupValue;
import com.wei.czz.common.dto.common.NameValue;
import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.framework.common.dao.RegionCodeDao;
import com.wei.czz.framework.common.entity.RegionCodeEntity;
import com.wei.czz.framework.common.service.RegionCodeService;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service("regionCodeService")
@AllArgsConstructor
public class RegionCodeServiceImpl extends ServiceImpl<RegionCodeDao, RegionCodeEntity> implements RegionCodeService {

    private static final Logger log = LoggerFactory.getLogger(RegionCodeServiceImpl.class);

    @Override
    public List<GroupValue<NameValue<Integer>>> getProvinceList() {
        LambdaQueryWrapper<RegionCodeEntity> regionCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 查询字段
        regionCodeLambdaQueryWrapper.select(RegionCodeEntity::getName, RegionCodeEntity::getFirstLetter,
                RegionCodeEntity::getCode);
        // 匹配条件
        regionCodeLambdaQueryWrapper.eq(RegionCodeEntity::getParentId, CommonEnum.ZERO.getValue())
                .eq(RegionCodeEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        List<RegionCodeEntity> regionCodeList = baseMapper.selectList(regionCodeLambdaQueryWrapper);
        if (regionCodeList.isEmpty()) {
            log.info("省份国标数据不存在");
            return Collections.emptyList();
        }
        // 数据封装
        return this.mapGroupValueList(regionCodeList);
    }

    @Override
    public List<GroupValue<NameValue<Integer>>> getCityList() {
        List<RegionCodeEntity> regionCodeList = baseMapper.getSunChildrenList(CommonEnum.ZERO.getValue(),
                CommonEnum.ZERO.getValue());
        if (regionCodeList.isEmpty()) {
            log.info("城市国标数据为空");
            return Collections.emptyList();
        }
        // 数据封装
        return this.mapGroupValueList(regionCodeList);
    }

    @Override
    public List<GroupValue<NameValue<Integer>>> getDistrictList() {
        List<RegionCodeEntity> regionCodeList = this.getLevelRegionList(CommonEnum.TWO.getValue());
        if (regionCodeList.isEmpty()) {
            log.info("区县国标地区数据为空");
            return Collections.emptyList();
        }
        // 数据封装
        return this.mapGroupValueList(regionCodeList);
    }

    @Override
    public List<GroupValue<NameValue<Integer>>> getStreetList() {
        List<RegionCodeEntity> regionCodeList = this.getLevelRegionList(CommonEnum.THREE.getValue());
        if (regionCodeList.isEmpty()) {
            log.info("街道国标地区数据为空");
            return Collections.emptyList();
        }
        // 数据封装
        return this.mapGroupValueList(regionCodeList);
    }


    @Override
    public List<GroupValue<NameValue<Integer>>> getChildrenList(Integer code) {

        LambdaQueryWrapper<RegionCodeEntity> regionCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 查询字段
        regionCodeLambdaQueryWrapper.select(RegionCodeEntity::getId);
        // 匹配条件
        regionCodeLambdaQueryWrapper.eq(RegionCodeEntity::getCode, code)
                .eq(RegionCodeEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        regionCodeLambdaQueryWrapper.last(" limit 1");
        // 查询
        List<RegionCodeEntity> regionCodeList = baseMapper.selectList(regionCodeLambdaQueryWrapper);
        if (regionCodeList.isEmpty()) {
            log.info("国标码【{}】关联数据不存在。", code);
            throw new RuntimeException(String.format("国标码【%s】不存在", code));
        }
        Long parentId = regionCodeList.get(0).getId();

        regionCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 查询字段
        regionCodeLambdaQueryWrapper.select(RegionCodeEntity::getName, RegionCodeEntity::getFirstLetter,
                RegionCodeEntity::getCode);
        // 匹配条件
        regionCodeLambdaQueryWrapper.eq(RegionCodeEntity::getParentId, parentId)
                .eq(RegionCodeEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        regionCodeList = baseMapper.selectList(regionCodeLambdaQueryWrapper);
        if (regionCodeList.isEmpty()) {
            log.info("国标码【{}】关联子数据为空", code);
            return Collections.emptyList();
        }
        // 数据封装
        return this.mapGroupValueList(regionCodeList);
    }

    @Override
    public Map<Integer, List<GroupValue<NameValue<Integer>>>> batchGetChildrenList(List<Integer> codeList) {

        LambdaQueryWrapper<RegionCodeEntity> regionCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 查询字段
        regionCodeLambdaQueryWrapper.select(RegionCodeEntity::getId, RegionCodeEntity::getCode);
        // 匹配条件
        regionCodeLambdaQueryWrapper.in(RegionCodeEntity::getCode, codeList)
                .eq(RegionCodeEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        List<RegionCodeEntity> regionCodeList = baseMapper.selectList(regionCodeLambdaQueryWrapper);
        if (regionCodeList.isEmpty()) {
            log.info("国标码【{}】关联数据不存在", codeList);
            return Collections.emptyMap();
        }

        List<Long> idList = new ArrayList<>(regionCodeList.size());
        Map<Long, Integer> map = new HashMap<>();
        for (RegionCodeEntity regionCode : regionCodeList) {
            idList.add(regionCode.getId());
            map.put(regionCode.getId(), regionCode.getCode());
        }

        regionCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 查询字段
        regionCodeLambdaQueryWrapper.select(RegionCodeEntity::getParentId, RegionCodeEntity::getName,
                RegionCodeEntity::getCode);
        // 匹配条件
        regionCodeLambdaQueryWrapper.in(RegionCodeEntity::getParentId, idList)
                .eq(RegionCodeEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        regionCodeList = baseMapper.selectList(regionCodeLambdaQueryWrapper);
        if (regionCodeList.isEmpty()) {
            log.info("国标码【{}】关联子数据为空", codeList);
            return Collections.emptyMap();
        }

        // 分组返回
        return regionCodeList.stream().collect(Collectors.groupingBy(
                regionCode -> {
                    Integer code = map.get(regionCode.getParentId());
                    if (Objects.isNull(code)) {
                        log.warn("父级主键关联父级code不存在，逻辑有问题。parentId={}", regionCode.getParentId());
                        throw new RuntimeException("服务开小差，请稍后重试");
                    }
                    return code;
                },
                Collectors.collectingAndThen(Collectors.toList(), this::mapGroupValueList)
        ));
    }

    @Override
    public List<RegionCodeEntity> getLevelRegionList(Integer level) {
        LambdaQueryWrapper<RegionCodeEntity> regionCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        regionCodeLambdaQueryWrapper.eq(RegionCodeEntity::getLevel, level)
                .eq(RegionCodeEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        List<RegionCodeEntity> regionCodeList = baseMapper.selectList(regionCodeLambdaQueryWrapper);
        log.info("查询四级国标地区完成。level={} isEmpty={}", level, regionCodeList.isEmpty());
        return regionCodeList;
    }

    @Override
    public String getName(Integer code) {

        LambdaQueryWrapper<RegionCodeEntity> regionCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 查询字段
        regionCodeLambdaQueryWrapper.select(RegionCodeEntity::getName);
        // 匹配条件
        regionCodeLambdaQueryWrapper.eq(RegionCodeEntity::getCode, code)
                .eq(RegionCodeEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        regionCodeLambdaQueryWrapper.last(" limit 1");
        // 查询
        List<RegionCodeEntity> regionCodeList = baseMapper.selectList(regionCodeLambdaQueryWrapper);
        if (regionCodeList.isEmpty()) {
            log.info("国标码【{}】不存在，获取名称失败", code);
            throw new RuntimeException(String.format("国标码【%s】不存在", code));
        }
        return regionCodeList.get(0).getName();
    }

    @Override
    public Map<Integer, String> batchGetName(Collection<Integer> codeCollection) {

        LambdaQueryWrapper<RegionCodeEntity> regionCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 查询字段
        regionCodeLambdaQueryWrapper.select(RegionCodeEntity::getName, RegionCodeEntity::getCode);
        // 匹配条件
        regionCodeLambdaQueryWrapper.in(RegionCodeEntity::getCode, codeCollection)
                .eq(RegionCodeEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        List<RegionCodeEntity> regionCodeList = baseMapper.selectList(regionCodeLambdaQueryWrapper);
        if (regionCodeList.isEmpty()) {
            log.info("国标码关联数据不存在，批量获取名称失败。codeCollection={}", codeCollection);
            return Collections.emptyMap();
        }
        // 映射
        return regionCodeList.stream().collect(
                Collectors.toMap(RegionCodeEntity::getCode, RegionCodeEntity::getName, (o1, o2) -> o1)
        );
    }

    /**
     * 地区数据列表映射封装
     * @param regionCodeList 地区数据列表
     * @return 封装结果
     */
    private List<GroupValue<NameValue<Integer>>> mapGroupValueList(List<RegionCodeEntity> regionCodeList) {
        Map<Character, List<NameValue<Integer>>> regionGroupMap = regionCodeList.stream().collect(Collectors.groupingBy(
                RegionCodeEntity::getFirstLetter,
                Collectors.mapping(regionCode -> new NameValue<>(regionCode.getName(), regionCode.getCode()), Collectors.toList())
        ));
        return regionGroupMap.entrySet()
                .stream()
                .map(entry -> new GroupValue<>(String.valueOf(entry.getKey()), entry.getValue()))
                .sorted(Comparator.comparing(GroupValue::getName))
                .collect(Collectors.toList());
    }

}